package org.yankun.exam4j.web.thread;

import java.io.Serializable;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;


/**
 * 管理当前执行线程的上下文信息，目前主要包括当前执行用户的信息
 * 
 * 线程上下文可提供统一的上下文信息访问方式，便于做横向的功能设计
 * @author wyz
 *
 */

@Component
public final class ThreadContextManager implements DisposableBean, InitializingBean {
	
	private static final Logger log = Logger.getLogger(ThreadContextManager.class);
	
	private ThreadLocal<ThreadContext> threadContext = new ThreadLocal<ThreadContext>();
	private static ThreadContextManager _singletion;
	
	public static final ThreadContextManager singletion() {
		return _singletion;
	}
	 
	
	public boolean isRegistered() {
		ThreadContext oi = threadContext.get();
		return oi!=null && (!oi.unregistered);
	}
	
	
	public void registerContext(Serializable userId, String username) {
		ThreadContext oi = threadContext.get();
		if (oi == null) {
			oi = new ThreadContext();
			threadContext.set(oi);
		}
		oi.unregistered = false;
		oi.userId = userId;
		oi.username = username;
	}
	
	public void unregisterContext() {
		ThreadContext oi = threadContext.get();
		if (oi != null && !oi.unregistered) {
			oi.unregistered = true;
		}
	}
	
	public ThreadContext getThreadContext() {
		ThreadContext retval =  threadContext.get();
		if (retval == null) {
			Thread current = Thread.currentThread();
			log.warn("警告, 获取的线程上下文为空; " +
					"Thread.name=" + current.getName() + 
					",Thread.id=" + current.getId() + 
					",ThreadGroup=" + current.getThreadGroup() + 
					",currentThreadStack=" + current.getStackTrace()[1]);
		}
		return retval;
	}

	@Override
	public void destroy() throws Exception {
		threadContext = null;
		_singletion = null;
	}


	@Override
	public void afterPropertiesSet() throws Exception {
		_singletion = this;
	}
	
	
}
